<?php

namespace App\Http\Controllers\Wechat;

use App\Http\Controllers\Controller;
use App\Http\Controllers\ScoreRuleController;
use App\Models\Scenic;
use App\Models\ScenicWorks;
use App\Models\ScenicWorksImg;
use App\Models\ScenicWorksVote;
use App\Models\UserInfo;
use App\Models\UserLibraryInfo;
use App\Models\UserViolate;
use App\Validate\ScenicWorksValidate;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
 * 景点打卡作品管理
 */
class ScenicWorksController extends Controller
{
    public $model = null;
    public $validate = null;
    public $score_type = 6;

    public function __construct()
    {
        parent::__construct();

        $this->model = new ScenicWorks();
        $this->validate = new ScenicWorksValidate();
    }


    /**
     * 列表
     * @param page int 当前页
     * @param limit int 分页大小
     * @param keywords string 搜索关键词(作品名称)
     * @param scenic_id 景点id
     * @param is_all 是否查询全部 1 查询全部(默认)，2 按用户查询
     * @param token 按用户查询时必传
     * @param status int 作品状态 0或空表示全部  1.已通过   2.未通过   3.未审核(默认)  4.已撤销  查询用户时有效
     */
    public function lists()
    {
        $page = request()->page ? intval(request()->page) : 1;
        $limit = request()->limit ? intval(request()->limit) : 10;
        $keywords = request()->keywords;
        $scenic_id = request()->scenic_id;
        $is_all = request()->input('is_all', 1);
        $status = request()->status;
        $user_id = $this->request->user_info['id'];

        if ($is_all == 2 && empty($user_id)) {
            return $this->returnApi(201, "用户token不能为空", true);
        }
        if ($is_all == 1) {
            $user_id = null;
            $is_violate = 1; //只查询好的
            $status = [1];
        } else {
            $status = empty($status) ? [1, 2, 3, 4] : [$status];
            $is_violate = null; //可查询违规
        }

        $res = $this->model->lists($scenic_id, $user_id, null, $keywords, $status, $is_violate, null, null, $limit);

        if (empty($res['data'])) {
            return $this->returnApi(203, "暂无数据");
        }
        foreach ($res['data'] as $key => $val) {
            $user_info = UserInfo::getWechatField($val['user_id'], ['nickname', 'head_img']);
            $res['data'][$key]['head_img'] = $user_info['head_img'];
            $res['data'][$key]['nickname'] = $user_info['nickname'];
            //判断用户是否点赞
            if ($user_id) {
                $scenicWorksVote = new ScenicWorksVote();
                $isVote = $scenicWorksVote->worksIsVote($val['user_id'], $val['scenic_id'], $val['id']);
                $res['data'][$key]['is_vote'] = $isVote ? true : false;
            } else {
                $res['data'][$key]['is_vote'] = false; //未登录默认未点赞
            }
        }
        $res = $this->disPageData($res);
        return $this->returnApi(200, "查询成功", "YES", $res);
    }

    /**
     * 详情
     * @param id int 作品id
     */
    public function detail()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('detail')->check($this->request->all())) {
            return $this->returnApi(201,  $this->validate->getError());
        }

        $id = $this->request->id;
        $user_id = $this->request->user_info['id'];
        $res = $this->model->detail($id);

        //增加浏览量,不是自己点击的才增加
        if ($this->request->user_info['id'] != $res['user_id']) {
            $res->browse_num = $res->browse_num + 1;
            $res->save();
        }


        $user_info = UserInfo::getWechatField($res['user_id'], ['nickname', 'head_img']);
        $res['head_img'] = $user_info['head_img'];
        $res['nickname'] = $user_info['nickname'];

        //判断用户是否点赞
        if ($user_id) {
            $scenicWorksVote = new ScenicWorksVote();
            $isVote = $scenicWorksVote->worksIsVote($user_id, $res['scenic_id'], $res['id']);
            $res['is_vote'] = $isVote ? true : false;
        } else {
            $res['is_vote'] = false; //未登录默认未点赞
        }

        return $this->returnApi(200, "查询成功", true, $res);
    }

    /**
     * 投稿
     * @param token  用户token
     * @param scenic_id int 景点id
     * @param title string 标题
     * @param intro string 简介
     * @param content string 作品内容 json 格式 
     * @param lon float 经度
     * @param lat float 纬度
     * json 格式：[{"img":"xxx.png","width":100,"height":100},{"img":"xxx2.png","width":200,"height":200}]
     * content [
            ['img'=>'xxx.png','width'=>100,'height'=>100],
            ['img'=>'xxx2.png','width'=>200,'height'=>200]
        ]
     * 
     */
    public function add()
    {
        if (!$this->validate->scene('wx_add')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }
        $user_id = $this->request->user_info['id'];
        $account_id = $this->request->user_info['account_id'];
        $scenic_id = $this->request->scenic_id;
        $title = $this->request->title;
        $intro = $this->request->intro;
        $content = $this->request->content;
        $content = json_decode($content, true);

        /*检查是否违规*/
        $validateModel = new UserViolate();
        $isViolate = $validateModel->checkIsViolate($user_id, 'scenic');
        if ($isViolate) {
            return $this->returnApi(201, '已达到违规次数上限,不能进行此操作');
        }
        $scenicModel = new Scenic();
        $scenic_info = $scenicModel->detail($scenic_id);

        if (empty($scenic_info) || $scenic_info['is_play'] == 2) {
            return $this->returnApi(202, '景点不存在');
        }
        if ($scenic_info['start_time'] > date('Y-m-d H:i:s')) {
            return $this->returnApi(202, '打卡时间未开始');
        }
        if ($scenic_info['end_time'] < date('Y-m-d H:i:s')) {
            return $this->returnApi(202, '打卡时间已结束');
        }

        //计算距离
        $distance = get_distance($this->request->lon, $this->request->lat, $scenic_info['lon'], $scenic_info['lat']);
        if ($distance > config('other.scenic_range')) {
            return $this->returnApi(202, '当前位置不在打卡范围内，不允许打卡');
        }


        //判断是否需要绑定读者证
        if ($scenic_info->is_reader == 1) {
            //判断读者证号密码是否正确 和是否绑定读者证
            $userLibraryInfoModel = new UserLibraryInfo();
            $account_lib_info = $userLibraryInfoModel->checkAccountPwdIsNormal($user_id);
            if (is_string($account_lib_info)) {
                return $this->returnApi(204, $account_lib_info);
            }
            $account_id = $account_lib_info['id'];
        }


        $works_num = $this->model->where('scenic_id', $scenic_id)->where('user_id', $user_id)->whereIn('status', [1, 2, 3, 4])->count();
        if ($works_num > 10) {
            return $this->returnApi(202, "此景点您打卡次数过多，请稍后重试");
        }

        //判断积分是否满足条件  
        // if (config('other.is_need_score') === true  && $scenic_info->is_reader == 1) {
        //     $scoreRuleObj = new ScoreRuleController();
        //     $score_status = $scoreRuleObj->checkScoreStatus($this->score_type, $user_id, $account_id);
        //     if ($score_status['code'] == 202) {
        //         return $this->returnApi(202, $score_status['msg']); //'积分不足无法参加活动'
        //     }
        // }

        // 启动事务
        DB::beginTransaction();
        try {
            $works_id = $this->model->add([
                'scenic_id' => $scenic_id,
                'user_id' => $user_id,
                'account_id' => $account_id ?? null,
                'title' => $title,
                'intro' => $intro,
                'status' => 3,
            ]);

            //添加作品图片
            $scenicWorksImgModel = new ScenicWorksImg();
            $scenicWorksImgModel->add($content, $this->model->id);

            $system_id = $this->systemAdd('景点打卡作品提交成功', $user_id, $account_id, 23, intval($works_id), '景点打卡作品：【' . $title . '】提交成功');

            //处理积分
            // if (!empty($score_status['code']) && $score_status['code'] == 200) {
            //     $scoreRuleObj->scoreChange($score_status, $user_id, $account_id, $system_id); //添加积分消息
            // }

            // 提交事务
            DB::commit();
            return $this->returnApi(200, "打卡成功,请等待管理员审核", true);
        } catch (\Exception $e) {
            Log::error($e->getMessage() . $e->getFile() . $e->getLine());
            $msg = $e->getCode() == 2002 ? $e->getMessage() : '打卡失败';
            // 回滚事务
            DB::rollBack();
            return $this->returnApi(202, $msg);
        }
    }

    /**
     * 修改作品
     * @param token  用户token
     * @param id int 作品id
     * @param scenic_id int 景点id
     * @param title string 标题
     * @param intro string 简介
     * @param content string 作品内容 json 格式 
     * 
     * content 
     * 
     */
    public function change()
    {
        if (!$this->validate->scene('wx_change')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }
        $user_id = $this->request->user_info['id'];
        $id = $this->request->id;
        $scenic_id = $this->request->scenic_id;
        $title = $this->request->title;
        $intro = $this->request->intro;
        $content = $this->request->content;
        $content = json_decode($content, true);

        // $content = [
        //     ['img'=>'xxx.png','width'=>100,'height'=>100],
        //     ['img'=>'xxx2.png','width'=>200,'height'=>200]
        // ];

        $scenicModel = new Scenic();
        $scenic_info = $scenicModel->detail($scenic_id);
        if (empty($scenic_info) || $scenic_info['is_play'] == 2) {
            return $this->returnApi(202, '景点不存在');
        }
        if ($scenic_info['start_time'] > date('Y-m-d H:i:s')) {
            return $this->returnApi(202, '打卡时间未开始');
        }
        if ($scenic_info['end_time'] < date('Y-m-d H:i:s')) {
            return $this->returnApi(202, '打卡时间已结束');
        }

        //判断是否需要绑定读者证
        if ($scenic_info->is_reader == 1) {
            //判断读者证号密码是否正确 和是否绑定读者证
            $userLibraryInfoModel = new UserLibraryInfo();
            $account_lib_info = $userLibraryInfoModel->checkAccountPwdIsNormal($user_id);
            if (is_string($account_lib_info)) {
                return $this->returnApi(204, $account_lib_info);
            }
            $account_id = $account_lib_info['id'];
        }

        $works_info = $this->model->where('id', $id)->where('user_id', $user_id)->first();
        if ($works_info != 2 || $works_info != 4) {
            return $this->returnApi(202, "请先撤销在进行修改");
        }


        // 启动事务
        DB::beginTransaction();
        try {
            $this->model->change([
                'id' => $id,
                'scenic_id' => $scenic_id,
                'user_id' => $user_id,
                'account_id' => $account_id ?? null,
                'title' => $title,
                'intro' => $intro,
                'status' => 3,
            ]);

            //添加作品图片
            $scenicWorksImgModel = new ScenicWorksImg();
            $scenicWorksImgModel->change($content, $this->model->id);

            $system_id = $this->systemAdd('景点打卡作品修改成功', $user_id, $account_id, 23, intval($id), '景点打卡作品：【' . $title . '】修改成功');

            // 提交事务
            DB::commit();
            return $this->returnApi(200, "修改成功,请等待管理员审核", true);
        } catch (\Exception $e) {
            Log::error($e->getMessage() . $e->getFile() . $e->getLine());
            $msg = $e->getCode() == 2002 ? $e->getMessage() : '打卡失败';
            // 回滚事务
            DB::rollBack();
            return $this->returnApi(202, $msg);
        }
    }

    /**
     * 打卡作品点赞与取消点赞
     * @param token  用户token
     * @param id int 作品id
     */
    public function worksVote()
    {

        if (!$this->validate->scene('wx_works_vote')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }

        $user_id = $this->request->user_info['id'];
        $id = $this->request->id;

        Log::info(date('Y-m-d H:i:s') . '~用户id：' . $user_id . '；景点作品id：' . $id . ';ip地址：' . request()->ip());

        // $ip = [
        //     '112.98.169.75',
        //     '222.180.68.57',
        //     '223.104.251.49',
        //     '183.230.215.93',
        // ];
        // if(in_array(request()->ip() , $ip)){
        //     return $this->returnApi(201, "系统检测到你存在刷票行为，暂时取消你的投票资格");
        // }

        //限制用户多次点击
        $key = md5($user_id . $id . request()->ip());

        $oldKey =  Cache::get($key); //没有缓存返回false
        if ($oldKey) {
            return $this->returnApi(201, "您操作的太频繁了，请稍后重试");
        } else {
            Cache::put($key, 1, 5);
        }

        $worksInfo = $this->model->find($id);
        if (empty($worksInfo)) {
            return $this->returnApi(201, "参数错误");
        }
        if ($worksInfo['status'] != 1) {
            return $this->returnApi(201, "当前状态不能点赞");
        }

        DB::beginTransaction();
        try {
            $scenicWorksVote = new ScenicWorksVote();
            $msg = $scenicWorksVote->voteAndCancel($user_id, $worksInfo['scenic_id'], $id);

            $vote_num = ScenicWorks::where('id', $id)->value('vote_num');
            DB::commit();
            return $this->returnApi(200, $msg . "成功", true, ['vote_num' => $vote_num]); //返回用户已投票数量
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->returnApi(202, "投票失败");
        }
    }


    /**
     * 撤销、删除作品
     * @param token  用户token
     * @param id 作品id
     * @param status 状态 4.已撤销， 5已删除 
     */
    public function  worksCancelAndDel()
    {
        //增加验证场景进行验证
        if (!$this->validate->scene('wx_works_cancel_del')->check($this->request->all())) {
            return $this->returnApi(201, $this->validate->getError());
        }
        if ($this->request->status != 4 && $this->request->status != 5) {
            return $this->returnApi(201, "参数错误");
        }
        $user_id = $this->request->user_info['id'];
        $account_id = $this->request->user_info['account_id'];

        $result = $this->model->find($this->request->id);
        if (empty($result)) {
            return $this->returnApi(201, "参数错误");
        }
        if ($result['user_id'] != $user_id) {
            return $this->returnApi(201, "网络错误");
        }
        if ($this->request->status == 4 &&  $result['status'] != 3) {
            return $this->returnApi(201, "此状态不允许撤销");
        } elseif ($this->request->status == 5 &&  ($result['status'] != 4 && $result['status'] != 2)) {
            return $this->returnApi(201, "此状态不允许删除");
        }
        DB::beginTransaction();
        try {
            $result->status = $this->request->status;
            $res = $result->save();

            /*消息推送*/
            $status_msg = $this->request->status == 5 ? '删除' : '撤销';
            $system_id = $this->systemAdd($status_msg . '打卡的作品', $user_id, $account_id, 24, intval($result->id), '作品：【' . $result->title . '】' . $status_msg . '成功');

            /**执行积分规则 */  //撤销才执行，因为删除的作品，必须是撤销的  不操作积分
            // if (!empty($result->score) && $this->request->status == 4) {
            //     $scoreRuleObj = new ScoreRuleController();
            //     $score_msg = $scoreRuleObj->getScoreMsg($result->score);
            //     $scoreRuleObj->scoreReturn($this->score_type, $result->score, $result->user_id, $result->account_id, '撤销作品，' . $score_msg . ' ' . abs($result->score) . ' 积分', $system_id);
            // }


            DB::commit();
            return $this->returnApi(200, $this->request->status == 5 ? "删除成功" : '撤销成功', true);
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->returnApi(202, $this->request->status == 5 ? "删除失败" : '撤销失败');
        }
    }
}
